<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // const p = new Promise((reslove, reject) => {
      //   // reslove(1);
      //   reject(2);
      // });

      // p.then(
      //   (ret) => {
      //     console.log(ret);
      //   },
      //   (e) => {
      //     console.log(e, 'eee');
      //   }
      // ).then((ret) => {
      //   console.log(ret, '2');
      // });

      class MyPromise {
        constructor(callback) {
          // 定义状态
          // pending fulfilled rejected
          this.state = 'pending';
          this.resloveValue = undefined;
          this.rejectValue = undefined;
          this.thens = [];
          this.catchs = [];
          if (!callback) {
            throw new Error('MyPromise must accept a function as a parameter');
          }
          try {
            callback(this.reslove.bind(this), this.reject.bind(this));
          } catch (error) {
            this.reject(error);
          }
        }

        then(onfulfilled, onrejected) {
          onfulfilled =
            typeof onfulfilled === 'function' ? onfulfilled : (val) => val;
          onrejected =
            typeof onrejected === 'function'
              ? onrejected
              : (error) => {
                  throw new Error(error);
                };
          const handler = function (callback, reslove, reject, v) {
            const data = callback(v);
            if (data instanceof MyPromise) {
              data.then(reslove, reject);
            } else {
              reslove(data);
            }
          };
          return new MyPromise((reslove, reject) => {
            if (this.state === 'pending') {
              this.thens.push((v) => {
                handler(onfulfilled, reslove, reject, v);
              });
              this.catchs.push((v) => {
                handler(onrejected, reslove, reject, v);
              });
            } else if (this.state === 'fulfilled') {
              handler(onfulfilled, reslove, reject, this.resloveValue);
              this.thens.push(() => {});
            } else {
              handler(onrejected, reslove, reject, this.rejectValue);
              this.catchs.push(() => {});
            }
          });
        }

        catch(onrejected) {
          return this.then(undefined, onrejected);
        }
      }

      MyPromise.prototype.reslove = function (value) {
        if (this.state === 'pending') {
          this.state = 'fulfilled';
          this.resloveValue = value;
          setTimeout(() => {
            if (this.thens.length) {
              this.thens.shift()(value);
            }
          });
        }
      };

      MyPromise.prototype.reject = function (reason) {
        if (this.state === 'pending') {
          this.state = 'rejected';
          this.rejectValue = reason;
          setTimeout(() => {
            if (this.catchs.length) {
              this.catchs.shift()(reason);
            } else {
              throw new Error(reason);
            }
          });
        }
      };
      const p2 = new MyPromise((reslove, reject) => {
        // reject(1231);
        // throw new Error(123);
        reslove(123);
      });
      // p2.catch((e) => {
      //   console.log('eee', e);
      // });
      p2.then((ret) => {
        console.log(ret);
        return new MyPromise((reslove) => {
          reslove(ret + 1);
        });
      }).then((ret) => {
        console.log(ret, '第二次结果');
      });
    </script>
  </body>
</html>
